package at.jku.cp.mir;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import org.apache.commons.io.IOUtils;

public class LastFmCommunicator
{

	// TODO extract API key to seperate file ?
	private final String API_KEY = "8ec7335b6962c3d765c2e651a43dbc41";
	private final String LAST_FM_API_BASE_URL = "http://ws.audioscrobbler.com/2.0/";

	public LastFmCommunicator()
	{
		super();
	}

	public byte[] downloadArtistTopTags(String lastFmArtistName) throws IOException
	{
		String url = constructUrlWithOneParameter("artist.getTopTags", "artist", lastFmArtistName);
		return downloadUrl(url);
	}

	public byte[] downloadArtistTopTracks(String lastFmArtistName) throws IOException
	{
		String url = constructUrlWithOneParameter("artist.getTopTracks", "artist", lastFmArtistName);
		return downloadUrl(url);
	}

	public byte[] downloadTrackTopTags(String lastFmArtistName, String trackName) throws IOException
	{
		Map<String, String> params = new HashMap<String, String>();
		params.put("artist", lastFmArtistName);
		params.put("track", trackName);
		String url = constructUrl("track.getTopTags", params);
		return downloadUrl(url);
	}

	protected final String constructUrl(String method, Map<String, String> params)
	{
		StringBuilder url = new StringBuilder(LAST_FM_API_BASE_URL);
		url.append("?api_key=").append(API_KEY);
		url.append("&method=").append(method);
		if (params.size() > 0)
		{
			Set<String> paramNames = params.keySet();
			for (String paramName : paramNames)
			{
				url.append("&").append(paramName).append("=");
				String paramValue = params.get(paramName);
				// url.append(encodeString(paramValue));
				url.append(paramValue);
			}
		}
		return url.toString();
	}

	protected final String constructUrlWithOneParameter(String method, String param, String paramValue)
	{
		Map<String, String> params = new HashMap<String, String>();
		params.put(param, paramValue);
		return constructUrl(method, params);
	}

	protected byte[] downloadUrl(String urlString) throws IOException
	{
		InputStream in = null;
		ByteArrayOutputStream out = null;
		try
		{
			URL url = new URL(urlString);
			in = url.openStream();

			out = new ByteArrayOutputStream();
			IOUtils.copy(in, out);

			return out.toByteArray();
		} catch (Exception e)
		{
			e.printStackTrace();
			throw new IOException("exception while downloading content", e);
		} finally
		{
			IOUtils.closeQuietly(in);
			IOUtils.closeQuietly(out);
		}
	}

	private String encodeString(String s)
	{
		try
		{
			return URLEncoder.encode(s, "UTF-8");
		} catch (UnsupportedEncodingException e)
		{
			e.printStackTrace();
			throw new RuntimeException("UTF-8 is not supported, wtf?", e);
		}
	}
}
